package com.xbongbong.paas.service.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.service.SmsSetService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.sms.model.SmsConfigModel;
import com.xbongbong.pro.sms.pojo.SmsSignPojo;
import com.xbongbong.pro.sms.pojo.SmsTemplatePojo;
import com.xbongbong.pro.sms.pojo.dto.SmsSignDelDTO;
import com.xbongbong.pro.sms.pojo.dto.SmsSignInfoDTO;
import com.xbongbong.pro.sms.pojo.dto.SmsSignSaveDTO;
import com.xbongbong.pro.sms.pojo.dto.SmsTemplateDelDTO;
import com.xbongbong.pro.sms.pojo.dto.SmsTemplateListDTO;
import com.xbongbong.pro.sms.pojo.dto.SmsTemplateSaveDTO;
import com.xbongbong.pro.sms.pojo.vo.SmsSignDelVO;
import com.xbongbong.pro.sms.pojo.vo.SmsSignInfoVO;
import com.xbongbong.pro.sms.pojo.vo.SmsSignSaveVO;
import com.xbongbong.pro.sms.pojo.vo.SmsTemplateDelVO;
import com.xbongbong.pro.sms.pojo.vo.SmsTemplateListVO;
import com.xbongbong.pro.sms.pojo.vo.SmsTemplateSaveVO;
import com.xbongbong.saas.constant.SmsSetConstant;
import com.xbongbong.saas.domain.entity.SmsConfigEntity;
import com.xbongbong.saas.domain.entity.SmsTemplateEntity;
import com.xbongbong.saas.enums.SmsSignStatusEnum;
import com.xbongbong.saas.enums.SmsTemplateStatusEnum;
import com.xbongbong.saas.model.SmsTemplateModel;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author youli.chen
 * @ProjectName xbb-pro
 * @Description: 短信配置
 * @date 2019/1/11 10:11
 */
@Service("smsSetService")
public class SmsSetServiceImpl implements SmsSetService {

    private static final Logger LOG = LoggerFactory.getLogger(SmsSetServiceImpl.class);

    @Resource
    private SmsConfigModel smsConfigModel;
    @Resource
    private SmsTemplateModel smsTemplateModel;
    @Resource
    private UserModel userModel;
    @Resource
    private CompanyModel companyModel;

    @Override
    public SmsSignInfoVO signInfo(SmsSignInfoDTO smsSignInfoDTO) throws XbbException {
        SmsSignInfoVO smsSignInfoVO = new SmsSignInfoVO();
        try {

            String corpid = smsSignInfoDTO.getCorpid();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());

            // 是否可以添加短信模板（有可用的短信签名）
            Boolean availableSign = false;

            List<SmsConfigEntity> configList = smsConfigModel.findEntitys(param);
            if (configList != null && configList.size() > 0) {
                SmsConfigEntity entity = configList.get(0);
                SmsSignPojo signPojo = new SmsSignPojo();
                BeanUtil.copyProperties(entity, signPojo);
                signPojo.setSignId(entity.getId());
                smsSignInfoVO.setSign(signPojo);
                availableSign = StringUtil.isNotEmpty(entity.getSign());
            }
            smsSignInfoVO.setAvailableSign(availableSign);
            // 是否有编辑权限
            boolean smsSetUpdate = Objects.nonNull(smsSignInfoDTO.getLoginUser())
                    && (smsSignInfoDTO.getLoginUser().isAdminOrBoss() || smsSignInfoDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.SMS_SET_UPDATE.getAlias()));
            smsSignInfoVO.setIsEdit(smsSetUpdate);

        } catch (Exception e) {
            LOG.error("短信设置获取出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return smsSignInfoVO;
    }

    @Override
    public SmsTemplateListVO templateList(SmsTemplateListDTO smsTemplateListDTO) throws XbbException {
        SmsTemplateListVO smsTemplateListVO = new SmsTemplateListVO();

        String corpid = smsTemplateListDTO.getCorpid();
        String nameLike = smsTemplateListDTO.getNameLike();
        Integer status = smsTemplateListDTO.getStatus();
        Integer page = smsTemplateListDTO.getPage();
        Integer pageSize = smsTemplateListDTO.getPageSize();

        nameLike = nameLike != null ? nameLike.trim() : null;
        page = page != null ? page : 1;
        pageSize = pageSize != null ? pageSize : 15;

        // 状态判断
        if (status != null) {
            SmsTemplateStatusEnum statusEnum = SmsTemplateStatusEnum.getByCode(status);
            if (statusEnum.equals(SmsTemplateStatusEnum.UNKNOWN)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015, "短信模板状态不正确");
            }
        }

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("nameLike", nameLike);
        param.put("status", status);
        param.put("orderByStr", "add_time desc");
        param.put("page", page);

        PageHelper pageHelper = PageHelperUtil.getPageHelper(param, smsTemplateModel, pageSize);
        try {
            // 是否有编辑权限
            boolean smsSetUpdate = Objects.nonNull(smsTemplateListDTO.getLoginUser())
                    && (smsTemplateListDTO.getLoginUser().isAdminOrBoss() || smsTemplateListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.SMS_SET_UPDATE.getAlias()));

            List<SmsTemplateEntity> list = (List<SmsTemplateEntity>) PageHelperUtil.getEntityList(param, pageHelper, smsTemplateModel);
            List<SmsTemplatePojo> templateList = toTemplatePojoList(list, smsSetUpdate);
            smsTemplateListVO.setPageHelper(pageHelper);
            smsTemplateListVO.setList(templateList);
        } catch (Exception e) {
            LOG.error("短信模板获取出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return smsTemplateListVO;
    }

    @Override
    public SmsTemplateSaveVO templateSave(SmsTemplateSaveDTO smsTemplateSaveDTO) throws XbbException {
        SmsTemplateSaveVO smsTemplateSaveVO = new SmsTemplateSaveVO();

        String corpid = smsTemplateSaveDTO.getCorpid();
        String userId = smsTemplateSaveDTO.getUserId();
        Long templateId = smsTemplateSaveDTO.getTemplateId();
        String name = smsTemplateSaveDTO.getName();
        String content = smsTemplateSaveDTO.getContent();
        try {

            SmsTemplateEntity entity = smsTemplateModel.getByKey(templateId, corpid);
            if (entity == null) {
                CompanyEntity companyEntity = companyModel.getByKey(corpid);
                if(companyEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
                }
                entity = new SmsTemplateEntity(corpid, companyEntity.getCorpName(), userId, name, content, "");
            } else {
                entity.setName(name);
                entity.setContent(content);
                // 是否修改状态
                // entity.setStatus(SmsTemplateStatusEnum.APPROVAL_ING.getCode());
            }
            smsTemplateModel.save(entity);

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("短信模板保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return smsTemplateSaveVO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public SmsSignSaveVO signSave(SmsSignSaveDTO smsSignSaveDTO) throws XbbException {
        SmsSignSaveVO smsSignSaveVO = new SmsSignSaveVO();

        String corpid = smsSignSaveDTO.getCorpid();
        String signNew = smsSignSaveDTO.getSignNew();
        signNew = signNew != null ? signNew.trim() : "";

        if (StringUtil.isEmpty(signNew)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100019, "短信新签名不能为空");
        }

        try {

            String userName = smsSignSaveDTO.getLoginUserName();
            Integer signStatus = SmsSignStatusEnum.APPROVAL_ING.getCode();

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("corpid", corpid);
            long now = DateUtil.getInt();
            List<SmsConfigEntity> configList = smsConfigModel.findEntitys(param);

            CompanyEntity companyEntity = companyModel.getByKey(corpid);
            if(companyEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
            }
            SmsConfigEntity entity;
            String memo;
            if (configList == null || configList.size() == 0) {
                memo = userName + I18nMessageUtil.getMessage(SmsSetConstant.APPLY_ING);
                entity = new SmsConfigEntity();
                entity.setCorpid(corpid);
                signStatus = SmsSignStatusEnum.APPLY_ING.getCode();

            } else {

                entity = configList.get(0);
                memo = entity.getMemo();
                memo = (memo == null) ? "" : memo;
                memo += userName + I18nMessageUtil.getMessage(SmsSetConstant.APPLY_ING);


                // 修改签名后，审核通过和审核中的模版需要设置为未通过
                List<Integer> statusIn = Arrays.asList(SmsTemplateStatusEnum.APPROVAL_ING.getCode(),
                        SmsTemplateStatusEnum.APPROVAL_SUCCESS.getCode());
                param.put("statusIn", statusIn);
                List<SmsTemplateEntity> templateList = smsTemplateModel.findEntitys(param);
                for (SmsTemplateEntity templateEntity : templateList) {
                    String templateMemo = templateEntity.getMemo();
                    if (null == templateMemo) {
                        templateMemo = "";
                    }
                    templateMemo += userName + I18nMessageUtil.getMessage(SmsSetConstant.TEMPLATE_MEMO_FAILURE);
                    templateEntity.setStatus(SmsTemplateStatusEnum.APPROVAL_FAILURE.getCode());
                    templateEntity.setMemo(templateMemo);
                    templateEntity.setApprovalMemo(I18nMessageUtil.getMessage(SmsSetConstant.TEMPLATE_APPROVAL_MEMO_FAILURE));

                    smsTemplateModel.update(templateEntity);
                }
            }

            entity.setCorpName(companyEntity.getCorpName());
            entity.setSignNew(signNew);
            entity.setStatus(signStatus);
            entity.setApplyTime(now);
            entity.setMemo(memo);

            smsConfigModel.save(entity);

        } catch (Exception e) {
            LOG.error("短信新签名保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return smsSignSaveVO;
    }

    @Override
    public SmsTemplateDelVO templateDel(SmsTemplateDelDTO smsTemplateDelDTO) throws XbbException {
        SmsTemplateDelVO smsTemplateDelVO = new SmsTemplateDelVO();
        try {
            String corpid = smsTemplateDelDTO.getCorpid();
            Long templateId = smsTemplateDelDTO.getTemplateId();
            SmsTemplateEntity entity = smsTemplateModel.getByKey(templateId, corpid);
            if (entity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "短信模板不存在");
            }
            smsTemplateModel.deleteByKey(templateId, corpid);

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("短信模板删除失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return smsTemplateDelVO;
    }

    @Override
    public SmsSignDelVO signNewDel(SmsSignDelDTO smsSignDelDTO) throws XbbException {
        SmsSignDelVO smsSignDelVO = new SmsSignDelVO();

        String corpid = smsSignDelDTO.getCorpid();
        String userId = smsSignDelDTO.getUserId();
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        if (userEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "用户不存在");
        }
        String userName = smsSignDelDTO.getLoginUserName();

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("corpid", corpid);

        try {
            List<SmsConfigEntity> configList = smsConfigModel.findEntitys(param);
            if (configList == null || configList.size() == 0) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "签名不存在");
            }

            SmsConfigEntity smsConfigEntity = configList.get(0);
            String memo = smsConfigEntity.getMemo();
            memo = (memo == null) ? "" : memo;
            memo += userName + I18nMessageUtil.getMessage(SmsSetConstant.SIGN_NEW_FAILURE_DELELTE);

            smsConfigEntity.setSignNew("");
            smsConfigEntity.setStatus(SmsSignStatusEnum.APPROVAL_SUCCESS.getCode());
            // 签名申请未通
            if(StringUtil.isEmpty(smsConfigEntity.getSign())) {
                smsConfigEntity.setStatus(SmsSignStatusEnum.APPLY_ING.getCode());
            }
            smsConfigEntity.setMemo(memo);

            smsConfigModel.update(smsConfigEntity);

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("短信新签名删除失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return smsSignDelVO;
    }

    /**
     * 短信模板列表转化为pojo列表
     *
     * @param list 短信模板列表
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-01-28 13:47
     * @version v1.0
     * @since v1.0
     */
    private List<SmsTemplatePojo> toTemplatePojoList(List<SmsTemplateEntity> list, boolean isEdit) {
        List<SmsTemplatePojo> resultList = new ArrayList<>();
        if (list == null || list.size() == 0) {
            return resultList;
        }

        for (SmsTemplateEntity entity : list) {
            boolean editBtn = false;
            boolean deleteBtn = false;
            Integer status = entity.getStatus();
            SmsTemplateStatusEnum statusEnum = SmsTemplateStatusEnum.getByCode(status);
            if(isEdit) {
                switch (statusEnum) {
                    case APPLY_ING:
                    case APPROVAL_SUCCESS:
                        deleteBtn = true;
                        break;
                    case APPROVAL_FAILURE:
                        deleteBtn = true;
                        editBtn = true;
                        break;
                    default:
                        break;
                }
            }

            SmsTemplatePojo templatePojo = new SmsTemplatePojo();
            BeanUtil.copyProperties(entity, templatePojo);
            templatePojo.setTemplateId(entity.getId());
            templatePojo.setStatusName(statusEnum.getName());
            templatePojo.setEditBtn(editBtn);
            templatePojo.setDeleteBtn(deleteBtn);
            resultList.add(templatePojo);
        }
        return resultList;
    }
}
